home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Freeware / sysmon / src / Timer.c < prev    next >
C/C++ Source or Header  |  2002-10-27  |  6KB  |  209 lines

  1. /*
  2. **    $RCSfile: Timer.c,v $
  3. **    $Filename: Timer.c $
  4. **    $Revision: 1.1 $
  5. **    $Date: 2001/04/28 17:30:19 $
  6. **
  7. **    sysmon command timer (version 1.1)
  8. **
  9. **    (C) Copyright 1995-2001 by Etienne Vogt
  10. */
  11.  
  12. #include <dos/rdargs.h>
  13. #include <dos/dostags.h>
  14. #include <dos/dosextens.h>
  15. #include <workbench/startup.h>
  16. #include <devices/timer.h>
  17. #define __USE_SYSBASE
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20. #include <proto/timer.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include "sysmon.h"
  25. #include "sysmon_protos.h"
  26. #include "sysmon_pragmas.h"
  27.  
  28. struct Library *SysmonBase;
  29. struct Device *TimerBase;
  30. static struct RDArgs *myrda;
  31. static struct WBStartup *wbmsg;
  32. static struct timerequest mytimereq;
  33.  
  34. int main(void);
  35. static void cleanexit(int rc);
  36. static struct EClockVal subEClockVal(struct EClockVal e2, struct EClockVal e1);
  37. static char *uptimestr(struct EClockVal *clockval, ULONG clockrate);
  38. static char *cputimestr(struct EClockVal *clockval, ULONG clockrate);
  39. static char *cpuloadstr(struct EClockVal *cpu, struct EClockVal *time);
  40. static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator, ULONG *remainder);
  41. static __inline APTR SPrintf(STRPTR buffer, STRPTR format, ...);
  42. void __asm __saveds comExit(register __d0 int rc, register __d1 struct EClockVal *data);
  43.  
  44. static UBYTE template[] = "COMMAND/F/A";
  45. static UBYTE version[] = "$VER: Timer 1.1 (28.4.2001)";
  46.  
  47. #define OPT_COMMAND    0
  48. #define OPTMAX        1
  49.  
  50.  
  51. int main(void)
  52. { LONG opts[OPTMAX];
  53.   struct CommandLineInterface *mycli;
  54.  
  55.   SysmonBase = NULL;
  56.   TimerBase = NULL;
  57.   wbmsg = NULL;
  58.   myrda = NULL;
  59.  
  60.   if (DOSBase->dl_lib.lib_Version < 37)
  61.   { Printf("Requires AmigaOS V37 or higher.\n");
  62.     exit(30);
  63.   }
  64.  
  65.   if (!(mycli = Cli()))
  66.     cleanexit(20);        /* If started from WB, exit cleanly */
  67.   else
  68.   { struct EClockVal StartTime, EndTime, ElapsedTime;
  69.     static struct EClockVal ElapsedCPU;
  70.     ULONG EClockRate;
  71.  
  72.     memset((char *)opts, 0, sizeof(opts));
  73.     if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
  74.     { PrintFault(IoErr(),NULL);
  75.       cleanexit(20);
  76.     }
  77.  
  78.     if ((SysmonBase = OpenLibrary("sysmon.library",0)) == NULL)
  79.     { PutStr("timer : Couldn't open sysmon.library\n");
  80.       cleanexit(20);
  81.     }
  82.  
  83.     if (OpenDevice(TIMERNAME, UNIT_ECLOCK, (struct IORequest *)&mytimereq, 0L))
  84.       cleanexit(100);
  85.     TimerBase = mytimereq.tr_node.io_Device;
  86.  
  87.     EClockRate = ReadEClock(&StartTime);
  88.     
  89.     if (SystemTags((STRPTR)opts[OPT_COMMAND],
  90.         SYS_UserShell,    TRUE,
  91.         NP_StackSize,    mycli->cli_DefaultStack << 2,
  92.         NP_ExitCode,    comExit,
  93.         NP_ExitData,    &ElapsedCPU,
  94.         TAG_DONE ))
  95.     { PrintFault(IoErr(), "Error starting command");
  96.       cleanexit(10);
  97.     }
  98.  
  99.     ReadEClock(&EndTime);
  100.     ElapsedTime = subEClockVal(EndTime, StartTime);
  101.  
  102.     Printf("Elapsed Time: %s , CPU Time: %s , CPU Load: %s\n",
  103.     uptimestr(&ElapsedTime, EClockRate),
  104.     cputimestr(&ElapsedCPU, EClockRate),
  105.     cpuloadstr(&ElapsedCPU, &ElapsedTime));
  106.   }
  107.   cleanexit(0);
  108. }
  109.  
  110. static void cleanexit(int rc)
  111. {
  112.   if (SysmonBase) CloseLibrary(SysmonBase);
  113.   if (TimerBase) CloseDevice((struct IORequest *)&mytimereq);
  114.   if (myrda) FreeArgs(myrda);
  115.   exit(rc);
  116. }
  117.  
  118. static struct EClockVal subEClockVal(struct EClockVal e2, struct EClockVal e1)
  119. { BOOL carry = (e1.ev_lo > e2.ev_lo);
  120.  
  121.   e2.ev_lo -= e1.ev_lo;
  122.   e2.ev_hi -= e1.ev_hi;
  123.   if (carry) e2.ev_hi -= 1;
  124.   return e2;
  125. }
  126.  
  127. static char *uptimestr(struct EClockVal *clockval, ULONG clockrate)
  128. { static char buffer[16];
  129.   ULONG seconds;
  130.   UWORD updays, uphours, upminutes, upseconds;
  131.  
  132.   seconds = EClockDivide(clockval, clockrate, NULL);
  133.   updays = seconds / (24*60*60);
  134.   seconds %= 24*60*60;
  135.   uphours = seconds / (60*60);
  136.   seconds %= 60*60;
  137.   upminutes = seconds / 60;
  138.   upseconds = seconds % 60;
  139.   SPrintf(buffer, "%3lu-%02lu:%02lu:%02lu", updays, uphours, upminutes, upseconds);
  140.   return buffer; 
  141. }
  142.  
  143. static char *cputimestr(struct EClockVal *clockval, ULONG clockrate)
  144. { static char buffer[18];
  145.   ULONG seconds, clockremain;
  146.   UWORD cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis;
  147.  
  148.   seconds = EClockDivide(clockval, clockrate, &clockremain);
  149.   cpudays = seconds / (24*60*60);
  150.   seconds %= 24*60*60;
  151.   cpuhours = seconds / (60*60);
  152.   seconds %= 60*60;
  153.   cpuminutes = seconds / 60;
  154.   cpuseconds = seconds % 60;
  155.   cpumillis = clockremain / (clockrate / 1000);
  156.   if (cpumillis == 1000) cpumillis--;
  157.   SPrintf(buffer, "%3lu-%02lu:%02lu:%02lu.%03lu", cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis);
  158.   return buffer;
  159. }
  160.  
  161. static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator, ULONG *remainder)
  162. { int bits;
  163.   ULONG d1,d2,d3;
  164.  
  165.   d1 = 0x0;
  166.   d2 = numerator->ev_hi;
  167.   d3 = numerator->ev_lo;
  168.  
  169.   for (bits = 0; bits < 64; bits++)
  170.   { /* now left-shift d1,d2,d3 */
  171.     d1 <<= 1;
  172.     if (d2 & 0x80000000) d1 |= 0x1;
  173.     d2 <<= 1;
  174.     if (d3 & 0x80000000) d2 |= 0x1;
  175.     d3 <<= 1;
  176.  
  177.     if (d1 >= denominator) 
  178.     { d1 -= denominator;
  179.       d3 |= 0x1;
  180.     }
  181.   }
  182.  
  183.   /* fill in the remainder */
  184.   if (remainder) *remainder = d1;
  185.  
  186.   /* return the quotient, or the low part of it, at least */
  187.   return d3;
  188. }
  189.  
  190. static char *cpuloadstr(struct EClockVal *cpu, struct EClockVal *time)
  191. { static char buffer[10];
  192.   double cpuload;
  193.  
  194.   cpuload = 100.0 * (cpu->ev_hi * 4294967296.0 + cpu->ev_lo) / (time->ev_hi * 4294967296.0 + time->ev_lo);
  195.   sprintf(buffer, "%5.1f %%", cpuload);
  196.   return buffer;
  197. }
  198.  
  199. static __inline APTR SPrintf(STRPTR buffer, STRPTR format, ...)
  200. { return smVSPrintf(buffer, format, &format + 1);
  201. }
  202.  
  203. void __asm __saveds comExit(register __d0 int rc, register __d1 struct EClockVal *data)
  204. { struct TaskInfo *mytinfo;
  205.  
  206.   mytinfo = smFindTaskInfo(NULL);
  207.   *data = mytinfo->ti_CPUTime;
  208. }
  209.